﻿module app.handler.payment.weixinpay;
import app.handler.payment.base;

import std.json;
import app.helper.appinfo;
import std.datetime;
import std.experimental.logger;
import std.conv;
import std.typetuple;
import std.typecons;
import std.algorithm.sorting;
import app.service.paybillservice;
import app.model;
import core.stdc.time;
import std.digest.md;
import std.string;
import arsd.dom;

enum string WEIXINPAY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";///统一下单
enum string WEIXINPAY_CALLBACK_URL = "https://spay.putao.com/weixinpay/callbak/";///统一下单
///微信APP支付
class WeixinPayHandler:PayHandlerBase
{
	
	override string[string] createBillAndSign(out string bill_id) {
		string[string] channelConfig = getAppChannelConfig();
		if(channelConfig is null)
		{
			throwExceptionBuild!"NotSupportChannel"("NotSupportChannel : ");	
		}
		//orderjson {"subject":"red apple","body":"red apple made in China","amount":100,"order_no":"1490862150","currency":"cny","extra":"[]","channel":"Alipay","client_ip":null,"appid":"c1d4d06048ed7342726955367350baba"}
		
		checkOutTradeNoIsPay();
		
		bill_id = saveBill();
		
		string[string] toSendData = [
			"appid": channelConfig["appid"],//支付宝分配的
			"mch_id":channelConfig["mch_id"],
			"notify_url":WEIXINPAY_CALLBACK_URL ~orderJson["appid"].str ~"-" ~orderJson["channel"].str,
			"nonce_str":bill_id,
			"sign_type":"MD5",
			"body":orderJson["body"].str,
			"out_trade_no":bill_id,
			"attach":orderJson["order_no"].str,
			"fee_type":"CNY",
			"total_fee":to!string(orderJson["amount"].integer),
			"spbill_create_ip":orderJson["client_ip"].str,
			"trade_type":getTradeType(),
			"sign":"",
			"openid":getOpenId()
		];
		string toSign = aaKsortSign(toSendData);
		import app.utils;
		toSendData["sign"] = toHexString(md5Of(toSign ~"&key=" ~channelConfig["key"])).idup;
		string sendxml = aa_xml(toSendData);
		trace("xml:", sendxml);
		string response = post(WEIXINPAY_ORDER_URL,sendxml) ;
		///TODO解析xml
		if(response.length == 0)
			throwExceptionBuild!"WeixinPrepayError"("WeixinPrepayError response is error");
		XmlDocument xml = new XmlDocument(response);
		if("SUCCESS" != xml.querySelector("return_code").directText() || "SUCCESS" != xml.querySelector("result_code").directText())
			throwExceptionBuild!"WeixinPrepayError"("WeixinPrepayError response is error " ~ xml.querySelector("return_msg").directText());
		
		// 扫码支付
		if( "NATIVE" == getTradeType() )
		{
			return ["code_url":xml.querySelector("code_url").directText];
		}
		// 公众号支付
		if( "JSAPI" == getTradeType() )
		{
			string[string] returnData = [
				"signType" : "MD5",
				"appid": xml.querySelector("appid").directText,
				"package": "prepay_id=" ~xml.querySelector("prepay_id").directText,
				"nonceStr": xml.querySelector("nonce_str").directText,
				"timeStamp":to!string(time(null)),
			];
			toSign = aaKsortSign(returnData);
			import app.utils;
			returnData["paySign"] = toHexString(md5Of(toSign ~"&key=" ~channelConfig["key"])).idup;
			returnData["package_"] = returnData["package"];
			return returnData;
		}
		
		//APP支付
		string[string] returnData = [
			"prepayid" : xml.querySelector("prepay_id").directText,
			"appid": xml.querySelector("appid").directText,
			"package": "Sign=WXPay",
			"noncestr": xml.querySelector("nonce_str").directText,
			"timestamp":to!string(time(null)),
			"partnerid":xml.querySelector("mch_id").directText,
		];
		toSign = aaKsortSign(returnData);
		import app.utils;
		returnData["sign"] = toHexString(md5Of(toSign ~"&key=" ~channelConfig["key"])).idup;
		returnData["package_"] = returnData["package"];
		return returnData;
	}
	
	string getTradeType(){
		return "APP";
	}
	
	string getOpenId(){
		return "";
	}
}

